#pragma once
#include <iostream>
#include <memory>
#include <string>
#include <jsoncpp/json/json.h>

static const std::string sep = "\r\n";

// 报文格式 len\r\n{joson}\r\n

// 将jsonstr格式的字符串加上报头
std::string Encode(const std::string &jsonstr)
{
    int len = jsonstr.size();
    std::string lenstr = std::to_string(len);
    return lenstr + sep + jsonstr + sep;
}

// 将接收到的数据中的joson段提取出来
std::string Decode(std::string &packagestream)
{
    // 分析
    auto pos = packagestream.find(sep);
    if (pos == std::string::npos)
    {
        return std::string();
    }

    std::string lenstr = packagestream.substr(0, pos);
    int len = std::stoi(lenstr);
    // 计算一个完整的报文应该多长
    int total = lenstr.size() + 2 * sep.size() + len;
    if (packagestream.size() < total)
    {
        return std::string();
    }
    // 提取
    std::string josonstr = packagestream.substr(pos + sep.size(), len);
    packagestream.erase(0, total);
    return josonstr;
}

class Request
{

public:
    Request() {}
    ~Request() {}

    Request(int x, int y, char oper)
        : _x(x), _y(y), _oper(oper)
    {
    }

    // 序列化
    bool Serialize(std::string *out)
    {
        // 使用joson库
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;
        Json::FastWriter write;
        std::string s = write.write(root);
        *out = s;
        return true;
    }
    // 反序列化
    bool Deserialize(const std::string &josonstr)
    {
        Json::Value root;
        Json::Reader reader;
        bool res = reader.parse(josonstr, root); // 将josonstr的内容提取到root中
        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _oper = root["oper"].asInt();
        return res;
    }

    void Print()
    {
        std::cout << _x << std::endl;
        std::cout << _y << std::endl;
        std::cout << _oper << std::endl;
    }

    int X()
    {
        return _x;
    }
    int Y()
    {
        return _y;
    }
    char Oper()
    {
        return _oper;
    }

    void SetValue(int x, int y, char oper)
    {
        _x = x;
        _y = y;
        _oper = oper;
    }

private:
    int _x;
    int _y;
    char _oper;
};

// 应答
class Response
{
public:
    ~Response() {}
    Response()
        : _result(0), _code(0), _desc("success")
    {
    }
    // 序列化
    bool Serialize(std::string *out)
    {
        // 使用joson库
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        root["desc"] = _desc;
        Json::FastWriter write;
        std::string s = write.write(root);
        *out = s;
        return true;
    }
    // 反序列化
    bool Deserialize(const std::string &josonstr)
    {
        Json::Value root;
        Json::Reader reader;
        bool res = reader.parse(josonstr, root); // 将josonstr的内容提取到root中
        _result = root["result"].asInt();
        _code = root["code"].asInt();
        _desc = root["desc"].asString();
        return res;
    }
    void PrintResult()
    {
        std::cout << "result: " << _result << " code: " << _code << " desc: " << _desc << std::endl;
    }

    int _result;
    int _code;
    std::string _desc;
};

class Factory
{
public:
    static std::shared_ptr<Request> BuildRequestDefault()
    {
        return make_shared<Request>();
    }

    static std::shared_ptr<Response> BuildResponseDefault()
    {
        return make_shared<Response>();
    }
};